// dart中 ? 的用法示例
void main() {
  print('1. 可空类型声明 (Nullable Type Declaration)：');
  // 使用 ? 声明可空变量
  String? nullableName; // 可以为 null
  print('nullableName: $nullableName'); // 输出: null

  int? age;
  print('age: $age'); // 输出: null

  // 不可空变量必须初始化
  String nonNullableName = 'John'; // 不能为 null
  // String nonNull; // 错误：非空变量必须初始化

  print('\n2. 条件属性访问 (?.)：');
  // 安全地访问可能为 null 的对象的属性
  String? text = null;
  print('text长度: ${text?.length}'); // 输出: null

  // 实际例子
  Person? person = null;
  print('person姓名: ${person?.name}'); // 输出: null

  person = Person('张三', 20);
  print('person姓名: ${person?.name}'); // 输出: 张三

  print('\n3. 空值合并运算符 (??)：');
  // 当值为 null 时提供默认值
  String? firstName;
  String displayName = firstName ?? '未知用户';
  print('显示名称: $displayName'); // 输出: 未知用户

  // 链式使用
  String? firstName2;
  String? lastName;
  String fullName = firstName2 ?? lastName ?? '匿名';
  print('完整名称: $fullName'); // 输出: 匿名

  print('\n4. 条件表达式 (? :)：');
  // 三元运算符
  bool isLoggedIn = true;
  String message = isLoggedIn ? '欢迎回来' : '请登录';
  print('消息: $message'); // 输出: 欢迎回来

  int number = 42;
  String result = number > 50 ? '大于50' : '小于或等于50';
  print('结果: $result'); // 输出: 小于或等于50

  print('\n5. 空值赋值运算符 (??=)：');
  // 只有当变量为 null 时才赋值
  String? username;
  username ??= '默认用户';
  print('用户名: $username'); // 输出: 默认用户
  
  username ??= '新用户'; // 不会改变值，因为username不为null
  print('用户名: $username'); // 输出: 默认用户

  print('\n6. 类型转换时的空检查 (as?)：');
  // 安全的类型转换，如果转换失败返回 null
  Object obj = 'Hello';
  // 错误示例
  try {
    int? numValue = obj as int?; // 这会抛出异常，因为String不能转换为int
    print('数值: $numValue');
  } catch (e) {
    print('转换失败: $e');
  }

  // 正确的类型转换示例
  print('\n正确的类型转换示例：');
  // 1. 字符串转数字
  String numberStr = '123';
  int? number1 = int.tryParse(numberStr); // 使用tryParse代替as?
  print('字符串转数字: $number1'); // 输出: 123

  String invalidNumber = 'abc';
  int? number2 = int.tryParse(invalidNumber);
  print('无效字符串转数字: $number2'); // 输出: null

  // 2. 对象类型转换
  Object someObject = Person('李四', 25);
  try {
    Person? person = someObject as Person?;
    print('成功转换为Person: ${person?.name}');
  } catch (e) {
    print('转换失败: $e');
  }

  // 3. 列表元素类型转换
  List<Object> mixedList = ['1', 2, '3', 4];
  List<int?> numbers = mixedList.map((e) {
    if (e is int) return e;
    if (e is String) return int.tryParse(e);
    return null;
  }).toList();
  print('列表转换结果: $numbers');

  print('\n7. 空值调用 (?[])：');
  // 安全地访问可能为 null 的列表
  List<int>? numbers2;
  print('第一个数字: ${numbers2?[0]}'); // 输出: null

  numbers2 = [1, 2, 3];
  print('第一个数字: ${numbers2?[0]}'); // 输出: 1

  print('\n8. 实际应用示例：');
  // 用户信息处理
  UserInfo? userInfo;
  // 链式调用，安全地访问嵌套属性
  print('用户地址: ${userInfo?.address?.city ?? '未知城市'}');

  userInfo = UserInfo(
    Address('北京', '朝阳区'),
    '13800138000',
  );
  print('用户地址: ${userInfo?.address?.city ?? '未知城市'}');
  print('用户电话: ${userInfo?.phone}');
}

// 示例类
class Person {
  final String name;
  final int age;

  Person(this.name, this.age);
}

class Address {
  final String city;
  final String street;

  Address(this.city, this.street);
}

class UserInfo {
  final Address? address;
  final String? phone;

  UserInfo(this.address, this.phone);
}
